package br.com.rapidrest.chain;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import br.com.rapidrest.exception.ChainException;
import br.com.rapidrest.ioc.FieldHandler;

public class IoCCommand implements Command {

	private List<FieldHandler> handlers;

	public IoCCommand() {
		super();
		this.handlers = new ArrayList<FieldHandler>();
	}

	@Override
	public void execute(Chain chain) throws ChainException {
		BasicChainContext context = (BasicChainContext) chain.getContext();

		Class<?> beanClass = context.getRequestScope().getBeanClass();
		inject(beanClass, context.getBean(), context);

		chain.proceed();
		
		end(beanClass, context.getBean(), context);
	}

	protected void inject(Class<?> clazz, Object target, BasicChainContext context)
			throws ChainException {
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			for (FieldHandler handler : handlers) {
				handler.handle(field, target, context);
			}
		}
		Class<?> superclass = clazz.getSuperclass();
		if (superclass != null) {
			inject(superclass, target, context);
		}
	}

	protected void end(Class<?> clazz, Object target, BasicChainContext context)
			throws ChainException {
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			for (FieldHandler handler : handlers) {
				handler.end(field, target, context);
			}
		}
		Class<?> superclass = clazz.getSuperclass();
		if (superclass != null) {
			end(superclass, target, context);
		}
	}

	public void addHandler(FieldHandler handler) {
		handlers.add(handler);
	}

}
